package com.chen.base.module.log.config;

import ch.qos.logback.classic.db.DBHelper;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.db.DBAppenderBase;
import com.chen.base.utils.PropertyUtil;
import com.chen.base.utils.basic.DateExUtil;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.time.LocalDateTime;

/**
 * logback日志输入到数据库
 */
@Deprecated
public class LoggerDBAppender extends DBAppenderBase<ILoggingEvent> {
 
    private static final int CREATE_TIME_INDEX = 1;
    private static final int MESSAGE_INDEX = 2;
    private static final int LEVEL_INDEX = 3;
    private static final int LOGGER_NAME_INDEX = 4;
    private static final int THREAD_NAME_INDEX = 5;
    private static final int REFERENCE_FLAG_INDEX = 6;
    private static final int CALLER_FILENAME_INDEX = 7;
    private static final int CALLER_CLASS_INDEX = 8;
    private static final int CALLER_METHOD_INDEX = 9;
    private static final int CALLER_LINE_INDEX = 10;
    private static final int APP_NAME_INDEX = 11;
    private static final String INSERT_SQL = "INSERT INTO sys_log (" +
                                             "create_time, message, level, logger_name, thread_name, reference_flag, " +
                                             "caller_filename, caller_class, caller_method, caller_line, app_name) " +
                                             "VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?)";
    private static String appName = "starting";

    /** sql参数赋值 */
    @Override
    protected void subAppend(ILoggingEvent event, Connection connection, PreparedStatement statement) throws Throwable {
        statement.setString(CREATE_TIME_INDEX, DateExUtil.format("d", LocalDateTime.now()));
        statement.setString(MESSAGE_INDEX, event.getFormattedMessage());
        statement.setString(LEVEL_INDEX, event.getLevel().toString());
        statement.setString(LOGGER_NAME_INDEX, event.getLoggerName());
        statement.setString(THREAD_NAME_INDEX, event.getThreadName());
        statement.setString(REFERENCE_FLAG_INDEX, String.valueOf(DBHelper.computeReferenceMask(event)));

        StackTraceElement call = CallerData.naInstance();
        StackTraceElement[] callArray = event.getCallerData();
        if (callArray != null && callArray.length > 0 && callArray[0] != null) {
            call = callArray[0];
        }

        statement.setString(CALLER_FILENAME_INDEX, call.getFileName());
        statement.setString(CALLER_CLASS_INDEX, call.getClassName());
        statement.setString(CALLER_METHOD_INDEX, call.getMethodName());
        statement.setString(CALLER_LINE_INDEX, Integer.toString(call.getLineNumber()));

        try {
            if ("starting".equals(appName)){
                appName = PropertyUtil.getProperty("spring.application.name");
            }
        }catch (Exception ignored){}
        statement.setString(APP_NAME_INDEX, appName);
        statement.executeUpdate();
    }

    /** sql语句 */
    @Override
    protected String getInsertSQL() {
        return INSERT_SQL;
    }

    @Override
    public void start() {
        super.start();
    }

    @Override
    protected Method getGeneratedKeysMethod() {
        try {
            return PreparedStatement.class.getMethod("getGeneratedKeys", (Class<?>[])null);
        } catch (Exception ignored) {}
        return null;
    }

    @Override
    protected void secondarySubAppend(ILoggingEvent iLoggingEvent, Connection connection, long l) throws Throwable {
    }
}